package com.chuyu.cy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chuyu.cy.contants.Constant;
import com.chuyu.cy.contants.PageResult;
import com.chuyu.cy.contants.ResponseCodeEnum;
import com.chuyu.cy.entity.domain.TemporaryNeeds;
import com.chuyu.cy.entity.domain.User;
import com.chuyu.cy.entity.dto.NeedDTO;
import com.chuyu.cy.entity.vo.NeedsVO;
import com.chuyu.cy.exception.CustomException;
import com.chuyu.cy.mapper.TemporaryNeedsMapper;
import com.chuyu.cy.mapper.UserMapper;
import com.chuyu.cy.service.TemporaryNeedsService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
* @author 周小白
* @description 针对表【temporary_needs(临时需求表)】的数据库操作Service实现
* @createDate 2024-03-15 15:59:13
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class TemporaryNeedsServiceImpl extends ServiceImpl<TemporaryNeedsMapper, TemporaryNeeds>
    implements TemporaryNeedsService{


    @Resource
    private TemporaryNeedsMapper temporaryNeedsMapper;
    @Resource
    private UserMapper userMapper;



    /**
     * 获取需求列表
     * @param kindId 需求类型id
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 需求列表
     */
    @Override
    public PageResult<NeedsVO> getNeedsList(Integer kindId, Integer pageNum, Integer pageSize) {
        if (kindId == null) {
            throw new CustomException("kindId不能为空");
        }

        PageResult<NeedsVO> pageResult = new PageResult<>();

        Integer pageStart = (pageNum - 1) * pageSize;
        List<NeedsVO> needsList = temporaryNeedsMapper.getNeedsList(kindId, pageStart, pageSize);

        needsList = Optional.ofNullable(needsList).orElse(new ArrayList<NeedsVO>());

        pageResult.setList(needsList);

        LambdaQueryWrapper<TemporaryNeeds> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TemporaryNeeds::getKindId, kindId);
        queryWrapper.eq(TemporaryNeeds::getIsMatched, Constant.IS_NOT_MATCHED);
        Long total = temporaryNeedsMapper.selectCount(queryWrapper);
        if (total == null) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        pageResult.setTotal(total);

        return pageResult;
    }




    /**
     * 修改需求信息
     * @param needDTO 需求信息
     * @return 修改结果
     */
    @Override
    public Integer updateNeeds(NeedDTO needDTO) {
        if (needDTO == null) {
            throw new CustomException("需求信息不能为空");
        }

        TemporaryNeeds temporaryNeeds = new TemporaryNeeds();
        temporaryNeeds.setId(needDTO.getId());
        temporaryNeeds.setKindId(needDTO.getKindId());
        temporaryNeeds.setTitle(needDTO.getTitle());
        if (needDTO.getLimitTime() != null) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            temporaryNeeds.setLimitTime(LocalDateTime.parse(needDTO.getLimitTime(), formatter));
        }
        temporaryNeeds.setAddress(needDTO.getAddress());
        temporaryNeeds.setPrice(needDTO.getPrice());
        temporaryNeeds.setDescription(needDTO.getDescription());

        int result = temporaryNeedsMapper.updateById(temporaryNeeds);

        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        return result;
    }




    /**
     * 删除需求
     * @param id 需求id
     * @return 删除结果
     */
    @Override
    public boolean deleteNeed(Integer id) {
        if (id == null) {
            throw new CustomException("id不能为空");
        }

        int result = temporaryNeedsMapper.deleteById(id);

        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        return true;
    }




    /**
     * 获取用户发布的需求列表
     * @param userId  用户id
     * @return 需求列表
     */
    @Override
    public PageResult<NeedsVO> getPublishedNeedsList(Integer userId, Integer pageNum, Integer pageSize) {
        if (userId == null) {
            throw new CustomException("userId不能为空");
        }

        PageResult<NeedsVO> pageResult = new PageResult<>();

        Integer pageStart = (pageNum - 1) * pageSize;
        List<NeedsVO> needsList = temporaryNeedsMapper.getPublishedNeedsList(userId, pageStart, pageSize);

        needsList = Optional.ofNullable(needsList).orElse(new ArrayList<NeedsVO>());

        pageResult.setList(needsList);

        LambdaQueryWrapper<TemporaryNeeds> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TemporaryNeeds::getCreateBy, userId);
        Long total = temporaryNeedsMapper.selectCount(queryWrapper);
        if (total == null) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        pageResult.setTotal(total);

        return pageResult;
    }




    /**
     * 获取用户匹配的需求列表
     * @param userId 用户id
     * @return 需求列表
     */
    @Override
    public PageResult<NeedsVO> getMatchedNeedsList(Integer userId, Integer pageNum, Integer pageSize) {
        if (userId == null) {
            throw new CustomException("userId不能为空");
        }

        PageResult<NeedsVO> pageResult = new PageResult<>();

        Integer pageStart = (pageNum - 1) * pageSize;
        List<NeedsVO> needsList = temporaryNeedsMapper.getMatchedNeedsList(userId, pageStart, pageSize);

        needsList = Optional.ofNullable(needsList).orElse(new ArrayList<NeedsVO>());

        pageResult.setList(needsList);

        LambdaQueryWrapper<TemporaryNeeds> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TemporaryNeeds::getMatcherId, userId);
        Long total = temporaryNeedsMapper.selectCount(queryWrapper);
        if (total == null) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        pageResult.setTotal(total);

        return pageResult;
    }




    /**
     * 获取用户未评价的需求列表
     * @param userId 用户id
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 需求列表
     */
    @Override
    public PageResult<NeedsVO> getUnratedNeedsList(Integer userId, Integer pageNum, Integer pageSize) {
        if (userId == null) {
            throw new CustomException("userId不能为空");
        }

        PageResult<NeedsVO> pageResult = new PageResult<>();

        Integer pageStart = (pageNum - 1) * pageSize;
        List<NeedsVO> needsList = temporaryNeedsMapper.getUnratedNeedsList(userId, pageStart, pageSize);

        needsList = Optional.ofNullable(needsList).orElse(new ArrayList<NeedsVO>());

        pageResult.setList(needsList);
        pageResult.setTotal((long) needsList.size());

        return pageResult;
    }




    /**
     * 获取用户已评分的需求列表
     * @param userId 用户id
     * @return 需求列表
     */
    @Override
    public PageResult<NeedsVO> getRatedNeedsList(Integer userId, Integer pageNum, Integer pageSize) {
        if (userId == null) {
            throw new CustomException("userId不能为空");
        }

        PageResult<NeedsVO> pageResult = new PageResult<>();

        Integer pageStart = (pageNum - 1) * pageSize;
        List<NeedsVO> needsList = temporaryNeedsMapper.getRatedNeedsList(userId, pageStart, pageSize);

        needsList = Optional.ofNullable(needsList).orElse(new ArrayList<NeedsVO>());

        pageResult.setList(needsList);
        pageResult.setTotal((long) needsList.size());

        return pageResult;
    }




    /**
     * 需求匹配
     * @param needId 需求id
     * @param matcherId 匹配者id
     * @return 匹配结果
     */
    @Override
    public boolean needMatched(Integer needId, Integer matcherId) {
        if (needId == null || matcherId == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }

        TemporaryNeeds temporaryNeeds = temporaryNeedsMapper.selectById(needId);
        if (temporaryNeeds == null) {
            throw new CustomException("此需求不存在");
        }
        if (temporaryNeeds.getIsMatched() == Constant.IS_MATCHED) {
            throw new CustomException("需求已匹配");
        }
        if (Objects.equals(temporaryNeeds.getCreateBy(), matcherId)) {
            throw new CustomException("不能匹配自己发布的需求");
        }
        if (temporaryNeeds.getLimitTime().isBefore(LocalDateTime.now())) {
            temporaryNeedsMapper.deleteById(needId);
            throw new CustomException("需求已过期，不能匹配");
        }

        temporaryNeeds.setIsMatched(Constant.IS_MATCHED);
        temporaryNeeds.setMatcherId(matcherId);
        temporaryNeeds.setMatchTime(LocalDateTime.now());

        int result = temporaryNeedsMapper.updateById(temporaryNeeds);

        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        return true;
    }





    /**
     * 发布者评分
     * @param needId 需求id
     * @param score 评分
     * @return 评分结果
     */
    @Override
    public boolean publisherRate(Integer needId, Integer score) {
        if (needId == null || score == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }

        TemporaryNeeds temporaryNeeds = temporaryNeedsMapper.selectById(needId);
        if (temporaryNeeds == null) {
            throw new CustomException("需求不存在");
        }
        if (temporaryNeeds.getIsMatched() == Constant.IS_NOT_MATCHED) {
            throw new CustomException("需求未匹配，不能评分");
        }
        if (temporaryNeeds.getPublisherEvaluation() != null) {
            throw new CustomException("需求已评分");
        }

        temporaryNeeds.setPublisherEvaluation(score);
        temporaryNeeds.setPublisherEvaluationTime(LocalDateTime.now());

        int result = temporaryNeedsMapper.updateById(temporaryNeeds);
        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        updateMatcherCredit(temporaryNeeds.getMatcherId());

        return true;
    }




    /**
     * 修改匹配者的信誉分
     * @param matcherId 匹配者id
     */
    public void updateMatcherCredit(Integer matcherId) {
        if (matcherId == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }

        List<TemporaryNeeds> matcherNeeds = temporaryNeedsMapper.getMatcherNeeds(matcherId);
        if (matcherNeeds == null || matcherNeeds.isEmpty()) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        int credit = 0;
        int count = 0;
        for (TemporaryNeeds item : matcherNeeds) {
            if (Objects.equals(item.getCreateBy(), matcherId)) {
                if (item.getMatcherEvaluation() == null) {
                    continue;
                }
                credit += item.getMatcherEvaluation();
                count++;
            } else {
                if (item.getPublisherEvaluation() == null) {
                    continue;
                }
                credit += item.getPublisherEvaluation();
                count++;
            }
        }

        User user = userMapper.selectById(matcherId);
        if (user == null) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }
        user.setCreditScore(credit / count);

        int result = userMapper.updateById(user);
        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

    }




    /**
     * 匹配者评分
     * @param needId 需求id
     * @param score 评分
     * @return 评分结果
     */
    @Override
    public boolean matcherRate(Integer needId, Integer score) {
        if (needId == null || score == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }

        TemporaryNeeds temporaryNeeds = temporaryNeedsMapper.selectById(needId);
        if (temporaryNeeds == null) {
            throw new CustomException("需求不存在");
        }
        if (temporaryNeeds.getIsMatched() == Constant.IS_NOT_MATCHED) {
            throw new CustomException("需求未匹配，不能评分");
        }
        if (temporaryNeeds.getMatcherEvaluation() != null) {
            throw new CustomException("需求已评分");
        }

        temporaryNeeds.setMatcherEvaluation(score);
        temporaryNeeds.setMatcherEvaluationTime(LocalDateTime.now());

        int result = temporaryNeedsMapper.updateById(temporaryNeeds);
        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        updatePublisherCredit(temporaryNeeds.getCreateBy());

        return true;
    }




    /**
     * 插入需求信息
     * @param needDTO 需求信息
     * @param userId 用户id
     * @return 插入结果
     */
    @Override
    public boolean insertNeeds(NeedDTO needDTO, Integer userId) {
        if (needDTO == null) {
            throw new CustomException(ResponseCodeEnum.NO_PARAM);
        }
        if (needDTO.getCreateBy() == null || needDTO.getTitle() == null
            || needDTO.getContact() == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        if (StringUtils.isNotBlank(needDTO.getLimitTime())) {
            if (LocalDateTime.now().isAfter(LocalDateTime.parse(needDTO.getLimitTime(), formatter))) {
                throw new CustomException("需求截止时间不能早于当前时间");
            }
        }


        TemporaryNeeds temporaryNeeds = new TemporaryNeeds();
        BeanUtils.copyProperties(needDTO, temporaryNeeds);
        if (StringUtils.isNotBlank(needDTO.getLimitTime())) {
            temporaryNeeds.setLimitTime(LocalDateTime.parse(needDTO.getLimitTime(), formatter));
        }
        temporaryNeeds.setLimitTime(LocalDateTime.now().plusDays(3));

        // 判断用户信誉分
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId, userId);
        queryWrapper.select(User::getCreditScore);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        // 判断用户未匹配需求数量
        LambdaQueryWrapper<TemporaryNeeds> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TemporaryNeeds::getCreateBy, userId);
        wrapper.eq(TemporaryNeeds::getIsMatched, Constant.IS_NOT_MATCHED);
        Long count = temporaryNeedsMapper.selectCount(wrapper);

        // 对用户的信誉分和未匹配需求数量进行是否满足判断
        int result;
        if (user.getCreditScore() < 60 && count >= 2) {
            throw new CustomException("评分低于60，未匹配需求只能存在2个");
        } else if (user.getCreditScore() < 80 && count >= 4) {
            throw new CustomException("评分低于80，未匹配需求只能存在4个");
        } else if (user.getCreditScore() < 90 && count >= 7) {
            throw new CustomException("评分低于90，未匹配需求只能存在7个");
        } else {
            result = temporaryNeedsMapper.insert(temporaryNeeds);
        }

        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        return true;
    }



    /**
     * 搜索需求
     * @param keyword 关键字
     * @param pageNum 页码
     * @param pageSize 页大小
     * @return 需求列表
     */
    @Override
    public PageResult<NeedsVO> searchNeeds(String keyword, Integer pageNum, Integer pageSize) {
        if (keyword == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }

        Page<TemporaryNeeds> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<TemporaryNeeds> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(TemporaryNeeds::getIsMatched, Constant.IS_NOT_MATCHED)
                .like(TemporaryNeeds::getTitle, keyword)
                .or()
                .like(TemporaryNeeds::getDescription, keyword);

        Page<TemporaryNeeds> selectPage = temporaryNeedsMapper.selectPage(page, queryWrapper);
        if (selectPage == null) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        List<TemporaryNeeds> records = selectPage.getRecords();
        if (records == null || records.isEmpty()) {
            throw new CustomException("未找到相关需求");
        }

        List<NeedsVO> needsVOList = new ArrayList<>();
        for (TemporaryNeeds item : records) {
            NeedsVO needsVO = new NeedsVO();
            BeanUtils.copyProperties(item, needsVO);
            needsVOList.add(needsVO);
        }
        PageResult<NeedsVO> pageResult = new PageResult<>();
        pageResult.setList(needsVOList);
        pageResult.setTotal(selectPage.getTotal());

        return pageResult;
    }




    /**
     * 获取需求详情
     * @param id 需求id
     * @return 需求详情
     */
    @Override
    public NeedsVO getNeedsDetail(Integer id) {
        if (id == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }

        TemporaryNeeds temporaryNeeds = temporaryNeedsMapper.selectById(id);
        if (temporaryNeeds == null) {
            throw new CustomException("需求不存在");
        }

        NeedsVO needsVO = BeanUtil.copyProperties(temporaryNeeds, NeedsVO.class);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId, temporaryNeeds.getMatcherId());
        queryWrapper.select(User::getContact);
        User matcher = userMapper.selectOne(queryWrapper);
        if (matcher != null) {
            needsVO.setMatcherContact(matcher.getContact());
        }

        needsVO.setLimitTime(needsVO.getLimitTime().replace("T", " "));

        return needsVO;
    }




    /**
     * 修改发布者的信誉分
     * @param publisherId 发布者id
     */
    public void updatePublisherCredit(Integer publisherId) {
        if (publisherId == null) {
            throw new CustomException(ResponseCodeEnum.ERROR_PARAM);
        }

        List<TemporaryNeeds> publisherNeeds = temporaryNeedsMapper.getPublishedNeeds(publisherId);
        if (publisherNeeds == null || publisherNeeds.isEmpty()) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        int credit = 0;
        int count = 0;
        for (TemporaryNeeds item : publisherNeeds) {
            if (Objects.equals(item.getCreateBy(), publisherId)) {
                if (item.getMatcherEvaluation() == null) {
                    continue;
                }
                credit += item.getMatcherEvaluation();
                count++;
            } else {
                if (item.getPublisherEvaluation() == null) {
                    continue;
                }
                credit += item.getPublisherEvaluation();
                count++;
            }
        }

        User user = userMapper.selectById(publisherId);
        if (user == null) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }

        user.setCreditScore(credit / count);

        int result = userMapper.updateById(user);
        if (result <= 0) {
            throw new CustomException(ResponseCodeEnum.SYSTEM_ERROR);
        }
    }


}






